package org.dbstar.scheduler.ldap;

import java.util.Collection;

import javax.naming.NamingException;
import javax.naming.directory.Attribute;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;

/**
 * 调度系统登录用户映射
 * 
 * @author 代波
 * @since 1.0.0
 * @version 1.0.0
 * @date 2012-5-28
 */
public class SchedulerUserDetailsContextMapper implements UserDetailsContextMapper {
	private static final Logger LOGGER = LoggerFactory.getLogger(SchedulerUserDetailsContextMapper.class);

	public static final GrantedAuthority SUPERVISOR = new SimpleGrantedAuthority("ROLE_SUPERVISOR");

	@Override
	public UserDetails mapUserFromContext(DirContextOperations ctx, String username,
			Collection<? extends GrantedAuthority> authorities) {

		String dn = ctx.getNameInNamespace();
		LOGGER.debug("Mapping user details from context with DN: {}", dn);

		SchedulerUserDetails details = new SchedulerUserDetails();
		details.setDn(dn);
		details.setUsername(username);

		try {
			Attribute streetAddress = ctx.getAttributes().get("streetAddress");
			Attribute displayName = ctx.getAttributes().get("displayName");
			if (streetAddress == null && displayName == null) {
				details.setDisplayName(username);
			} else if (streetAddress == null && displayName != null) {
				details.setDisplayName(displayName.get().toString());
			} else if (streetAddress != null && displayName == null) {
				details.setDisplayName(streetAddress.get().toString());
			} else if (streetAddress != null && displayName != null) {
				details.setDisplayName(streetAddress.get() + "(" + displayName.get() + ")");
			}
		} catch (NamingException e) {
			details.setDisplayName(username);
		}

		// Add the supplied authorities
		if (authorities == null || authorities.isEmpty()) {
			details.addAuthority(new SimpleGrantedAuthority("GROUP_ANONYMOUS"));
		} else {
			for (GrantedAuthority authority : authorities) {
				details.addAuthority(new SimpleGrantedAuthority("GROUP_" + authority.getAuthority().replace(' ', '_')));
			}
		}
		if ("bdai".equals(username)) {
			details.addAuthority(SUPERVISOR);
		}

		return details;
	}

	@Override
	public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {
		throw new UnsupportedOperationException(
				"SchedulerUserDetailsContextMapper only supports reading from a context.");
	}
}
